package control

import (
	"antServer/antPublic"
	"encoding/json"
	"path/filepath"
	"strings"
	"time"

	"gopkg.in/yaml.v2"

	"io/ioutil"
	"os"
)

// ServerConfig 服务器配置
type ServerConfig struct {
	ServerName string `json:"serverName" yaml:"serverName"`
	ServerAddr string `json:"serverAddr" yaml:"serverAddr"`
	//是否启动集群模式
	//mongodb配置
	Mongodb          *MongodbConfig `json:"mongodb" yaml:"mongodb"`
	serverConfigFile string
	MqttClient       *MqttClientConfig `json:"mqttClient" yaml:"mqttClient"`
	CachePath        string
	Authorize        *antPublic.AuthorizeConfig `json:"authorize" yaml:"authorize"`
}

// MqttClientConfig mqtt客户端配置
type MqttClientConfig struct {
	BrokerAddress     string        `json:"brokerAddress" yaml:"brokerAddress"`
	ClientIDPrefix    string        `json:"clientIdPrefix" yaml:"clientIdPrefix"`
	Keepalive         time.Duration `json:"keepalive" yaml:"keepalive"`
	ClientIDFileName  string        `json:"clientIdFileName" yaml:"clientIdFileName"`
	MqttKeyURL        string        `json:"mqttKeyUrl" yaml:"mqttKeyUrl"`
	ReconnectInterval time.Duration `json:"reconnectInterval" yaml:"reconnectInterval"`
}

// MongodbConfig mongodb数据库配置
type MongodbConfig struct {
	URL string `json:"url" yaml:"url"`
	//异步任务最大执行数量
	AsyncPoolNum int64 `json:"asyncPoolNum" yaml:"asyncPoolNum"`
	//异步任务最大等待数量
	AsyncMaxWaitTaskNum int `json:"asyncTaskMaxFaildedNum" yaml:"asyncTaskMaxFaildedNum"`
	//最大空闲时间,空闲时间到自动回收 单位秒
	AsyncPoolIdelTime int `json:"asyncPoolIdelTime" yaml:"asyncPoolIdelTime"`
	//异步任务最大重复执行次数,超过后放弃
	AsyncTaskMaxFaildedNum uint64 `json:"asyncTaskMaxExeNum" yaml:"asyncTaskMaxExeNum"`
	DBName                 string `json:"dbName" yaml:"dbName"`
}

// CreateDefaultConfig 创建默认服务
func CreateDefaultConfig() *ServerConfig {
	sc := &ServerConfig{}
	sc.loadConfig()
	return sc
}

// CreateConfig 通过配置文件创建配置
func CreateConfig(configfile string) *ServerConfig {
	sc := &ServerConfig{serverConfigFile: configfile}
	sc.loadConfig()
	return sc
}

func (l *ServerConfig) loadConfig() {
	l.initConfig()
	l.execConfig()
}

func (l *ServerConfig) execConfig() {
	//alog.RegisterAlog(l.LogConfigFile)

}
func (l *ServerConfig) initConfig() {
	defer func() {
		if err := recover(); err != nil {
			//defaultConfig()
			Tlog.Error("配置文件解析错误", err)
		}
		//环境变量参数设置优先级高于配置文件
		l.parseEnv()
	}()
	Tlog.Debug("初始化配置文件")
	l.defaultConfig()
	if l.serverConfigFile != "" {
		l.parseConfigByFile(l.serverConfigFile)
	}
}
func (l *ServerConfig) defaultConfig() {
	l.ServerName = "monitor"
	l.ServerAddr = ":1883"

	l.Mongodb = &MongodbConfig{
		AsyncMaxWaitTaskNum:    1024,
		AsyncPoolNum:           16,
		AsyncPoolIdelTime:      30,
		AsyncTaskMaxFaildedNum: 5,
	}

}

//通过指定的文件解析配置
func (l *ServerConfig) parseConfigByFile(file string) {
	data, err := ioutil.ReadFile(file)
	if err != nil {

		Tlog.Error("配置解析失败:", err)
		panic(err)

	}
	switch strings.ToLower(filepath.Ext(file)) {
	case ".yaml":
		l.parseConfigYaml(data)
	case ".json":
		l.parseConfigJSON(data)
	default:
		panic("配置文件名后缀错误")
	}
}

//解析配置
func (l *ServerConfig) parseConfigYaml(configdata []byte) {

	err := yaml.Unmarshal(configdata, l)
	if err != nil {
		Tlog.Error("配置解析失败:", err)
		panic(err)
	}

}

//解析配置
func (l *ServerConfig) parseConfigJSON(configdata []byte) {

	err := json.Unmarshal(configdata, l)
	if err != nil {
		Tlog.Error("配置解析失败:", err)
		panic(err)
	}

}

//解析系统环境变量中的参数
func (l *ServerConfig) parseEnv() {
	tmp := os.Getenv("MQTT_EGG_SERVERNAME")
	if tmp != "" {
		l.ServerName = tmp
	}
}
